#ifndef __MSGPROCDISPATCHER_HPP__
#define __MSGPROCDISPATHCER_HPP__

#include "../common.h"
#include <stdlib.h>

/**
*@file       msgprocdispathcer.h
*@brief      helper class for message process
*
*@author     graywind
*@version    1.0.0.0
*@data       2011/12/30
*/

///static message mapping class
template<class Operator, eOperateType type>
class OperateTypeDispatcher;

template<class Operator, eOperateType type>
class OperateTypeDispatcher
{
public:
        static void OnDispatch(Operator* p, int session_id, void* pMsgBuffer, unsigned long msgID, unsigned long msg_bytes, int error_code)
        {
                ///@brief    error occurs
                std::abort();
        }
};

///static function pointer holder
template<class Operator>
class DispatcherFuncPtr
{
public:
        typedef void(*MsgProcDispatchFunc)(Operator* p, int session_id, void* pMsgBuffer, unsigned long msgID, unsigned long msg_bytes, int error_code);

public:
        enum {MAX_OPERATE = 6};

public:
        static const MsgProcDispatchFunc FuncPtrArray[MAX_OPERATE];
};

template<class Operator>
const typename DispatcherFuncPtr<Operator>::MsgProcDispatchFunc  DispatcherFuncPtr<Operator>::FuncPtrArray[MAX_OPERATE] = {
                                                                                                                        OperateTypeDispatcher<Operator, Listen>::OnDispatch,
                                                                                                                        OperateTypeDispatcher<Operator, Connect>::OnDispatch,
																														OperateTypeDispatcher<Operator, Kick>::OnDispatch,
																														OperateTypeDispatcher<Operator, Disconnect>::OnDispatch,
                                                                                                                        OperateTypeDispatcher<Operator, Send>::OnDispatch,
                                                                                                                        OperateTypeDispatcher<Operator, Read>::OnDispatch,
                                                                                                                       };

///message dispatcher
class MsgProcDispatcher
{
private:

public:
	template<class Operator>
	static void dispatch(Operator* p, eOperateType type, int session_id, void* pMsgBuffer, unsigned long msgID, unsigned long msg_bytes, int error_code)
	{
	        DispatcherFuncPtr<Operator>::FuncPtrArray[type](p, session_id, pMsgBuffer, msgID, msg_bytes, error_code);
	}
};

///@brief    register dispatch handler with macro, handler must defined a static function named OnDispatch();
#define RegisterMsgProcDispatcher(Operator, type, handler) \
template<>\
class OperateTypeDispatcher<Operator, type> : public handler\
{\
};


#endif
